home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / intuisup.lha / Intuisup / source.lha / Gadgets / gadgets2.c < prev    next >
C/C++ Source or Header  |  1992-08-08  |  50KB  |  1,552 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1991 by Torsten Jürgeleit
  4.  *
  5.  *    Name .....: gadgets2.c
  6.  *    Created ..: Thursday 19-Dec-91 20:52:53
  7.  *    Revision .: 7
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    08-Aug-92   Torsten Jürgeleit      alternate justifications (center,
  12.  *                       right) of string in input gadget
  13.  *    11-Jul-92   Torsten Jürgeleit      eg_Hotkey now always in lower case
  14.  *    01-Jul-92   Torsten Jürgeleit      added support for custom slider
  15.  *                                         knob image
  16.  *    23-Apr-92   Torsten Jürgeleit      now all PRINTABLE characters can
  17.  *                                         be used as hotkeys
  18.  *    01-Apr-92   Torsten Jürgeleit      any references to gadget data
  19.  *                                         via gl_Data removed
  20.  *    25-Mar-92   Torsten Jürgeleit      now the ASCII chars `!'..`/' and
  21.  *                                         `:'..`@' can be used as hotkeys
  22.  *    05-Jan-92   Torsten Jürgeleit      now try to open font before
  23.  *                                         initializing gadget;
  24.  *                                         correct display of larger fonts
  25.  *                                         for mutual exclude gadgets
  26.  *    19-Dec-91   Torsten Jürgeleit      Created this file!
  27.  *
  28.  ****************************************************************************
  29.  *
  30.  *    Gadget support routines - part 2
  31.  *
  32.  * $Revision Header ********************************************************/
  33.  
  34.     /* Includes */
  35.  
  36. #include <exec/types.h>
  37. #include <exec/memory.h>
  38. #include <devices/inputevent.h>
  39. #include <intuition/intuition.h>
  40. #ifdef AZTEC_C
  41. #include <functions.h>   /* needed for Aztec C - prototypes and pragmas for all Amiga system functions */
  42. #endif
  43. #include <libraries/memwatch.h>   /* header file for memory debug link library (Fish 240) - AFTER functions.h */
  44. #include <string.h>
  45. #include "/render/render.h"
  46. #include "/texts/texts.h"
  47. #include "/borders/borders.h"
  48. #include "/language/language.h"
  49. #include "gadgets.h"
  50. #include "imports.h"
  51.  
  52.     /* Count entries in gadget data array */
  53.  
  54.    USHORT
  55. count_gadget_data_entries(struct GadgetData  *gd)
  56. {
  57.    USHORT data_entries = 0;
  58.  
  59.    while (gd->gd_Type != INTUISUP_DATA_END &&
  60.                       gd->gd_Type <= MAX_GADGET_DATA_TYPE) {
  61.       data_entries++;
  62.       gd++;
  63.    }
  64.    return(data_entries);
  65. }
  66.     /* Get buffer size for gadgets and borders */
  67.  
  68.    ULONG
  69. get_gadget_buffer_size(struct GadgetList  *gl, struct GadgetData  *gd)
  70. {
  71.    struct RenderInfo  *ri = gl->gl_RenderInfo;
  72.    USHORT i, data_entries = gl->gl_DataEntries;
  73.    ULONG  buffer_size = 0;
  74.  
  75.    for (i = 0; i < data_entries; i++, gd++) {
  76.       BYTE   **text;
  77.       USHORT gadget_size, border_size, num, height, spacing,
  78.          type = gd->gd_Type;
  79.       ULONG  flags = gd->gd_Flags;
  80.  
  81.       /* If monochrome display then set HIGHCOMP flag */
  82.       if (ri->ri_ScreenDepth == 1) {
  83.      flags |= GADGET_DATA_FLAG_HIGH_COMP;
  84.       }
  85.       switch(type) {
  86.      case GADGET_DATA_TYPE_BUTTON :
  87.         gadget_size = sizeof(struct ExtendedGadget);
  88.         if ((flags & GADGET_DATA_FLAG_BUTTON_TOGGLE &&
  89.                    flags & GADGET_DATA_FLAG_BUTTON_IMAGE) ||
  90.                        flags & GADGET_DATA_FLAG_HIGH_COMP) {
  91.            border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  92.         } else {
  93.            border_size = 2 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  94.         }
  95.  
  96.         /* Add image struct size if chip mem copies of image data needed */
  97.         if (gd->gd_Flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  98.            if (check_gadget_image(gd->gd_SpecialData.gd_ButtonData.
  99.                       gd_ButtonNormalRender) == FALSE) {
  100.           buffer_size += sizeof(struct Image);
  101.            }
  102.            if (check_gadget_image(gd->gd_SpecialData.gd_ButtonData.
  103.                       gd_ButtonSelectRender) == FALSE) {
  104.           buffer_size += sizeof(struct Image);
  105.            }
  106.         }
  107.         break;
  108.  
  109.      case GADGET_DATA_TYPE_CHECK :
  110.         gadget_size = sizeof(struct ExtendedGadget);
  111.         border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  112.         break;
  113.  
  114.      case GADGET_DATA_TYPE_MX :
  115.         text = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
  116.         num  = 0;
  117.         while (*text++) {
  118.            num++;
  119.         }
  120.         gadget_size = num * (sizeof(struct ExtendedGadget) +
  121.               sizeof(struct IntuiText)) + sizeof(struct MXData);
  122.         border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  123.         break;
  124.  
  125.      case GADGET_DATA_TYPE_STRING :
  126.      case GADGET_DATA_TYPE_INTEGER :
  127.  
  128.         /* Calc size of input buffer */
  129.         if (type == GADGET_DATA_TYPE_STRING) {
  130.            num = gd->gd_SpecialData.gd_InputData.gd_InputLen;
  131.            if (flags & (GADGET_DATA_FLAG_STRING_UNSIGNED_DEC |
  132.                     GADGET_DATA_FLAG_STRING_SIGNED_DEC |
  133.                            GADGET_DATA_FLAG_STRING_HEX |
  134.                          GADGET_DATA_FLAG_STRING_BIN)) {
  135.           if (num < (MAX_BIN_NUM_DIGITS + 1)) {
  136.              num = MAX_BIN_NUM_DIGITS + 1;   /* identifier `%' + number */
  137.           }
  138.            }
  139.         } else {
  140.            num = MAX_DEC_NUM_DIGITS;
  141.         }
  142.         if (num & 1) {   /* odd input len ? */
  143.            num += 1;
  144.         } else {
  145.            num += 2;   /* inc for end of string marker */
  146.         }
  147.         gadget_size = sizeof(struct ExtendedGadget) +
  148.          sizeof(struct StringInfo) + num + sizeof(struct InputData);
  149.         border_size = BORDER_TYPE_BOX2_BUFFER_SIZE;
  150.         break;
  151.  
  152.      case GADGET_DATA_TYPE_SLIDER :
  153.         gadget_size = sizeof(struct ExtendedGadget) +
  154.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  155.                           sizeof(struct SliderData);
  156.         border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  157.         break;
  158.  
  159.      case GADGET_DATA_TYPE_SCROLLER :
  160.         if (flags & GADGET_DATA_FLAG_SCROLLER_NO_ARROWS) {
  161.            gadget_size = sizeof(struct ExtendedGadget) +
  162.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  163.                         sizeof(struct ScrollerData);
  164.            border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  165.         } else {
  166.            gadget_size = 3 * sizeof(struct ExtendedGadget) +
  167.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  168.                         sizeof(struct ScrollerData);
  169.            if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  170.           border_size = 3 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  171.            } else {
  172.           border_size = 5 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  173.            }
  174.         }
  175.         break;
  176.  
  177.      case GADGET_DATA_TYPE_CYCLE :
  178.         gadget_size = sizeof(struct ExtendedGadget) +
  179.                            sizeof(struct CycleData);
  180.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  181.            border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  182.         } else {
  183.            border_size = 2 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  184.         }
  185.         break;
  186.  
  187.      case GADGET_DATA_TYPE_COUNT :
  188.         gadget_size = sizeof(struct ExtendedGadget) +
  189.                            sizeof(struct CountData);
  190.         border_size = 2 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  191.         break;
  192.  
  193.      case GADGET_DATA_TYPE_LISTVIEW :
  194.         if (flags & GADGET_DATA_FLAG_LISTVIEW_READ_ONLY) {
  195.            num = 0;
  196.         } else {
  197.            struct TextAttr  *ta;
  198.  
  199.            if (!(ta = gd->gd_TextAttr)) {
  200.           ta = &gl->gl_RenderInfo->ri_TextAttr;
  201.            }
  202.            height  = gd->gd_Height;
  203.            spacing = gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing;
  204.            if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  205.           height -= 2 * 1;
  206.            }
  207.            num = (height + spacing) / (ta->ta_YSize + spacing);
  208.         }
  209.         gadget_size = (3 + num) * sizeof(struct ExtendedGadget) +
  210.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  211.                         sizeof(struct ListViewData);
  212.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  213.            border_size = 4 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  214.         } else {
  215.            border_size = 6 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  216.         }
  217.         break;
  218.  
  219.      case GADGET_DATA_TYPE_PALETTE :
  220.         num         = 1L << gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth;
  221.         gadget_size = num * (sizeof(struct ExtendedGadget) +
  222.              sizeof(struct Image)) + sizeof(struct PaletteData);
  223.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  224.            border_size = num * BORDER_TYPE_BOX1_BUFFER_SIZE;
  225.         } else {
  226.            border_size = num * (2 * BORDER_TYPE_BOX1_BUFFER_SIZE);
  227.         }
  228.         if (!(flags & GADGET_DATA_FLAG_PALETTE_NO_INDICATOR)) {
  229.            gadget_size += sizeof(struct ExtendedGadget) +
  230.                                sizeof(struct Image);
  231.            border_size += BORDER_TYPE_BOX1_BUFFER_SIZE;
  232.         }
  233.         break;
  234.       }
  235.       buffer_size += gadget_size;
  236.       if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  237.      buffer_size += border_size;
  238.       }
  239.    }
  240.    return(buffer_size);
  241. }
  242.     /* Get buffer size for image data */
  243.  
  244.    ULONG
  245. get_image_buffer_size(struct GadgetList  *gl, struct GadgetData  *gd)
  246. {
  247.    USHORT i, data_entries = gl->gl_DataEntries;
  248.    ULONG  buffer_size = 0;
  249.  
  250.    for (i = 0; i < data_entries; i++, gd++) {
  251.       switch (gd->gd_Type) {
  252.      case GADGET_DATA_TYPE_BUTTON :
  253.         if (gd->gd_Flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  254.            struct Image  *image;
  255.  
  256.            image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonNormalRender;
  257.            if (check_gadget_image(image) == FALSE) {
  258.           buffer_size += (image->Width / 16 + (image->Width & 15 ?
  259.                  1 : 0)) * image->Height * image->Depth * 2;
  260.            }
  261.            image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonSelectRender;
  262.            if (check_gadget_image(image) == FALSE) {
  263.           buffer_size += (image->Width / 16 + (image->Width & 15 ?
  264.                  1 : 0)) * image->Height * image->Depth * 2;
  265.            }
  266.         }
  267.         break;
  268.  
  269.      case GADGET_DATA_TYPE_SLIDER :
  270.         if (gd->gd_Flags & GADGET_DATA_FLAG_SLIDER_IMAGE) {
  271.            struct Image  *image;
  272.  
  273.            image = (struct Image *)gd->gd_TextAttr;
  274.            if (check_gadget_image(image) == FALSE) {
  275.           buffer_size += (image->Width / 16 + (image->Width & 15 ?
  276.                  1 : 0)) * image->Height * image->Depth * 2;
  277.            }
  278.         }
  279.         break;
  280.       }
  281.    }
  282.    return(buffer_size);
  283. }
  284.     /* Initialize gadgets from gadget list */
  285.  
  286.    VOID
  287. init_gadgets(struct GadgetList  *gl, struct GadgetData  *gd,
  288.                            SHORT hoffset, SHORT voffset)
  289. {
  290.    struct RenderInfo  *ri = gl->gl_RenderInfo;
  291.    BYTE   *buffer = gl->gl_GadgetBuffer, *image_buffer = gl->gl_ImageBuffer;
  292.    USHORT i, data_entries = gl->gl_DataEntries;
  293.  
  294.    for (i = 0; i < data_entries; i++, gd++) {
  295.       struct ExtendedGadget  *egad, *first_egad;
  296.       struct Image           *image;
  297.       struct IntuiText       itext;
  298.       struct MXData          *mx;
  299.       struct InputData       *id;
  300.       struct SliderData      *sl;
  301.       struct ScrollerData    *sc;
  302.       struct CycleData       *cy;
  303.       struct CountData       *co;
  304.       struct ListViewData    *lv;
  305.       struct PaletteData     *pd;
  306.       struct TextAttr        *ta;
  307.       struct TextFont        *tf;
  308.       BYTE   **text;
  309.       USHORT j, max_width, num, len, xoffset, yoffset, xmin, ymin,
  310.          xnum, ynum, yinc, spacing, text_height,
  311.          type = gd->gd_Type, left_edge = gd->gd_LeftEdge + hoffset,
  312.          top_edge = gd->gd_TopEdge + voffset, width = gd->gd_Width,
  313.          height = gd->gd_Height;
  314.       ULONG  min, max, flags = gd->gd_Flags;
  315.  
  316.       /* Get ptr to extended gadget and reserve buffer */
  317.       egad    = gl->gl_Gadgets[i] = (struct ExtendedGadget *)buffer;
  318.       buffer += sizeof(struct ExtendedGadget);
  319.  
  320.       /* Save ptr to first gadget of ISUP object */
  321.       first_egad = egad;
  322.  
  323.       /* Save absolut gadget position - needed by modify_gadget() */
  324.       egad->eg_BorderLeftEdge = left_edge;
  325.       egad->eg_BorderTopEdge  = top_edge;
  326.  
  327.       /* Open text font and save data */
  328.       if (type == GADGET_DATA_TYPE_SLIDER &&
  329.                   (flags & GADGET_DATA_FLAG_SLIDER_IMAGE)) {
  330.      /* Use default font */
  331.      ta = &ri->ri_TextAttr;
  332.      tf = ri->ri_TextFont;
  333.       } else {
  334.  
  335.      /* Use font given in gd_TextAttr */
  336.      if (!(ta = gd->gd_TextAttr) || !(ta = ask_font(ri, ta))) {
  337.  
  338.         /* Use default font */
  339.         ta = &ri->ri_TextAttr;
  340.         tf = ri->ri_TextFont;
  341.      } else {
  342.         if (!(tf = open_font(ri, ta))) {
  343.  
  344.            /* Use default font */
  345.            ta = &ri->ri_TextAttr;
  346.            tf = ri->ri_TextFont;
  347.         } else {
  348.            egad->eg_Flags |= EXTENDED_GADGET_FLAG_CLOSE_FONT;
  349.         }
  350.      }
  351.       }
  352.       egad->eg_TextAttr = ta;
  353.       egad->eg_TextFont = tf;
  354.       text_height       = ta->ta_YSize;
  355.  
  356.       /* Init intui text */
  357.       itext.ITextFont = ta;
  358.  
  359.       /* Calc border offsets */
  360.       if (flags & GADGET_DATA_FLAG_NO_BORDER) {
  361.      xoffset = 0;
  362.      yoffset = 0;
  363.       } else {
  364.      switch (type) {
  365.         case GADGET_DATA_TYPE_MX :
  366.            xoffset = 8;
  367.            yoffset = 4;
  368.            break;
  369.  
  370.         case GADGET_DATA_TYPE_STRING :
  371.         case GADGET_DATA_TYPE_INTEGER :
  372.            xoffset = 6;
  373.            yoffset = 3;
  374.            break;
  375.  
  376.         case GADGET_DATA_TYPE_CYCLE :
  377.         case GADGET_DATA_TYPE_COUNT :
  378.            xoffset = 2;
  379.            yoffset = 1;
  380.            break;
  381.  
  382.         default :
  383.            xoffset = 4;
  384.            yoffset = 2;
  385.            break;
  386.      }
  387.       }
  388.  
  389.       /* Inner window position needed ? */
  390.       if (ri->ri_Flags & RENDER_INFO_FLAG_INNER_WINDOW) {
  391.      left_edge += ri->ri_WindowBorderLeft;
  392.      top_edge  += ri->ri_WindowBorderTop;
  393.       }
  394.  
  395.       /* If fixed gadget dimensions or data buffers so init them yet */
  396.       switch (type) {
  397.      case GADGET_DATA_TYPE_CHECK :
  398.  
  399.         /* Calc fixed dimensions of check gadget */
  400.         width  = IMAGE_CHECK_WIDTH + 2 * IMAGE_HORIZ_OFFSET;
  401.         height = IMAGE_CHECK_HEIGHT + 2 * IMAGE_VERT_OFFSET;
  402.         break;
  403.  
  404.      case GADGET_DATA_TYPE_MX :
  405.  
  406.         /* Calc fixed dimensions of mx gadget */
  407.         width  = IMAGE_KNOB_WIDTH;
  408.         height = IMAGE_KNOB_HEIGHT;
  409.  
  410.         /* Calc vertical offset between mx gadget */
  411.         if ((yinc = text_height) < height) {
  412.            yinc = height;
  413.         }
  414.         yinc += gd->gd_SpecialData.gd_MXData.gd_MXSpacing;
  415.  
  416.         /* Count mx gadgets and calc maximal text width */
  417.         text      = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
  418.         num       = 0;
  419.         max_width = 0;
  420.         while (*text) {
  421.            itext.IText = (UBYTE *)get_language_text(*text++,
  422.                           gl->gl_LanguageTextArray);
  423.            if ((len = IntuiTextLength(&itext)) > max_width) {
  424.           max_width = len;
  425.            }
  426.            num++;
  427.         }
  428.  
  429.         /* Left and top edge of gadget */
  430.         if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  431.            left_edge += max_width + xoffset + 8;
  432.         } else {
  433.            left_edge += xoffset;
  434.         }
  435.         if (text_height > height) {
  436.            top_edge += (text_height - height) / 2 + yoffset;
  437.         } else {
  438.            top_edge += yoffset;
  439.         }
  440.  
  441.         /* Init mx data */
  442.         mx                 = (struct MXData *)buffer;
  443.         buffer            += sizeof(struct MXData);
  444.         mx->mx_TextEntries = num;
  445.         break;
  446.  
  447.      case GADGET_DATA_TYPE_STRING :
  448.      case GADGET_DATA_TYPE_INTEGER :
  449.  
  450.         /* Calc fixed height of input gadgets */
  451.         height = ri->ri_TextAttr.ta_YSize + 2 * yoffset;
  452.  
  453.         /* Init input data */
  454.         id                  = (struct InputData *)buffer;
  455.         buffer             += sizeof(struct InputData);
  456.         id->id_ActivateNext = gd->gd_SpecialData.gd_InputData.gd_InputActivateNext;
  457.         id->id_ActivatePrev = gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev;
  458.         break;
  459.  
  460.      case GADGET_DATA_TYPE_SLIDER :
  461.  
  462.         /* Init slider data */
  463.         sl      = (struct SliderData *)buffer;
  464.         buffer += sizeof(struct SliderData);
  465.         break;
  466.  
  467.      case GADGET_DATA_TYPE_SCROLLER :
  468.  
  469.         /* Calc minimum dimensions of scroller gadget */
  470.         if (!(flags & GADGET_DATA_FLAG_SCROLLER_NO_ARROWS)) {
  471.            xmin = IMAGE_ARROW_WIDTH + IMAGE_HORIZ_OFFSET + xoffset;
  472.            ymin = IMAGE_ARROW_HEIGHT + IMAGE_VERT_OFFSET + yoffset;
  473.            if (flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
  474.           if (width < xmin) {
  475.              width = xmin;
  476.           }
  477.           if (height < 3 * ymin) {
  478.              height = 3 * ymin;
  479.           }
  480.            } else {
  481.           if (width < 3 * xmin) {
  482.              width = 3 * xmin;
  483.           }
  484.           if (height < ymin) {
  485.              height = ymin;
  486.           }
  487.            }
  488.         }
  489.  
  490.         /* Init scroller data */
  491.         sc      = (struct ScrollerData *)buffer;
  492.         buffer += sizeof(struct ScrollerData);
  493.         break;
  494.  
  495.      case GADGET_DATA_TYPE_CYCLE :
  496.  
  497.         /* Init cycle data */
  498.         cy      = (struct CycleData *)buffer;
  499.         buffer += sizeof(struct CycleData);
  500.         break;
  501.  
  502.      case GADGET_DATA_TYPE_COUNT :
  503.  
  504.         /* Init count data */
  505.         co      = (struct CountData *)buffer;
  506.         buffer += sizeof(struct CountData);
  507.         break;
  508.  
  509.      case GADGET_DATA_TYPE_LISTVIEW :
  510.  
  511.         /* Calc minimum dimension of list view gadget */
  512.         xmin = IMAGE_ARROW_WIDTH + IMAGE_HORIZ_OFFSET + xoffset;
  513.         ymin = IMAGE_ARROW_HEIGHT + IMAGE_VERT_OFFSET + yoffset;
  514.         if (height < 3 * ymin) {
  515.            height = 3 * ymin;
  516.         }
  517.         spacing = gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing;
  518.         yinc    = text_height + spacing;
  519.         num     = (height - 2 * yoffset + spacing) / yinc;
  520.         height  = num * yinc + 2 * yoffset;
  521.  
  522.         /* Init list view data */
  523.         lv      = (struct ListViewData *)buffer;
  524.         buffer += sizeof(struct ListViewData);
  525.         break;
  526.  
  527.      case GADGET_DATA_TYPE_PALETTE :
  528.  
  529.         /* Calc dimension of color squares of palette */
  530.         min  = gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset;
  531.         max  = 1L << gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth;
  532.         xnum = max;   /* start with all squares in a horizontal line */
  533.         ynum = 1;
  534.         while (xnum > 1 && (width / xnum) / 2 < height / ynum) {
  535.            xnum /= 2;
  536.            ynum *= 2;
  537.         }
  538.         if (!(flags & GADGET_DATA_FLAG_PALETTE_NO_INDICATOR)) {
  539.  
  540.            /* Insert color indicator */
  541.            if (flags & GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP) {
  542.           ynum++;
  543.            } else {
  544.           xnum++;
  545.            }
  546.         }
  547.  
  548.         /* Calc gadget dimension */
  549.         if (xnum == 1) {
  550.            xmin = width;
  551.         } else {
  552.            xmin  = (width - 2 * (xnum - 1)) / xnum;
  553.            width = xmin * xnum + 2 * (xnum - 1);
  554.         }
  555.         if (ynum == 1) {
  556.            ymin = height;
  557.         } else {
  558.            ymin   = (height - 1 * (ynum - 1)) / ynum;
  559.            height = ymin * ynum + 1 * (ynum - 1);
  560.         }
  561.  
  562.         /* Init palette data */
  563.         pd      = (struct PaletteData *)buffer;
  564.         buffer += sizeof(struct PaletteData);
  565.         break;
  566.       }
  567.  
  568.       /* Init gadget */
  569.       switch (type) {
  570.      case GADGET_DATA_TYPE_BUTTON :
  571.         buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  572.             EXTENDED_GADGET_TYPE_BUTTON, left_edge, top_edge, width,
  573.                                     height);
  574.         break;
  575.  
  576.      case GADGET_DATA_TYPE_CHECK :
  577.         buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  578.              EXTENDED_GADGET_TYPE_CHECK, left_edge, top_edge, width,
  579.                                     height);
  580.         break;
  581.  
  582.      case GADGET_DATA_TYPE_MX :
  583.  
  584.         /* Init all mx gadgets */
  585.         text = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
  586.         for (j = 0; j < num; j++, text++) {
  587.            buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  588.             EXTENDED_GADGET_TYPE_MX, left_edge, top_edge, width,
  589.                                     height);
  590.            buffer = init_mx_text(egad, buffer, get_language_text(*text,
  591.                gl->gl_LanguageTextArray), width, height, flags, ta);
  592.            egad->eg_Gadget.GadgetID = j;   /* num of mx gadget */
  593.            if (j < (num - 1)) {   /* another mx gadget ? */
  594.           top_edge += yinc;
  595.           egad      = egad->eg_NextGadget =
  596.                         (struct ExtendedGadget *)buffer;
  597.           buffer   += sizeof(struct ExtendedGadget);
  598.            }
  599.         }
  600.  
  601.         /* Calc border offsets first - need old height */
  602.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  603.            if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  604.           left_edge = -(max_width + xoffset + 8);
  605.            } else {
  606.           left_edge = -xoffset;   /* default right */
  607.            }
  608.            if (text_height > height) {
  609.           top_edge = -((text_height - height) / 2 + yoffset);
  610.            } else {
  611.           top_edge = -yoffset;
  612.            }
  613.         }
  614.  
  615.         /* Calc border dimension and draw it */
  616.         width += max_width + 2 * xoffset + 8;
  617.         height = yinc * num + 2 * yoffset -
  618.                   gd->gd_SpecialData.gd_MXData.gd_MXSpacing;
  619.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  620.            first_egad->eg_Render = (APTR)buffer;
  621.            buffer                = init_border(ri, buffer, left_edge,
  622.              top_edge, width, height, BORDER_DATA_TYPE_BOX1_IN);
  623.            first_egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_BORDER;
  624.         }
  625.         break;
  626.  
  627.      case GADGET_DATA_TYPE_STRING :
  628.         buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  629.             EXTENDED_GADGET_TYPE_STRING, left_edge, top_edge, width,
  630.                                     height);
  631.         break;
  632.  
  633.      case GADGET_DATA_TYPE_INTEGER :
  634.         buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  635.            EXTENDED_GADGET_TYPE_INTEGER, left_edge, top_edge, width,
  636.                                     height);
  637.         break;
  638.  
  639.      case GADGET_DATA_TYPE_SLIDER :
  640.  
  641.         /* Init slider data */
  642.         sl->sl_Min = gd->gd_SpecialData.gd_SliderData.gd_SliderMin;
  643.         sl->sl_Max = gd->gd_SpecialData.gd_SliderData.gd_SliderMax;
  644.         buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  645.               EXTENDED_GADGET_TYPE_SLIDER_PROP, left_edge, top_edge,
  646.                                  width, height);
  647.         break;
  648.  
  649.      case GADGET_DATA_TYPE_SCROLLER :
  650.  
  651.         /* Init scroller data */
  652.         sc->sc_Total   = gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTotal;
  653.         sc->sc_Visible = gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerVisible;
  654.  
  655.         /* Init scroller gadgets */
  656.         if (flags & GADGET_DATA_FLAG_SCROLLER_NO_ARROWS) {
  657.            buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  658.                   EXTENDED_GADGET_TYPE_SCROLLER_PROP, left_edge,
  659.                            top_edge, width, height);
  660.         } else {
  661.            if (flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
  662.  
  663.           /* Create vertical scroller - prop gadget first */
  664.           buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  665.                   EXTENDED_GADGET_TYPE_SCROLLER_PROP, left_edge,
  666.                   top_edge, width, height - 2 * (ymin + 1));
  667.           /* Init scroller up arrow gadget */
  668.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  669.                                      buffer;
  670.           buffer += sizeof(struct ExtendedGadget);
  671.           buffer  = init_extended_gadget(egad, buffer, gl, gd, i,
  672.                 EXTENDED_GADGET_TYPE_SCROLLER_UP, left_edge,
  673.                  top_edge + height - 2 * ymin - 1, width, ymin);
  674.           /* Change type of vertical scroller arrow gadget for correct counting */
  675.           egad->eg_Type = EXTENDED_GADGET_TYPE_SCROLLER_DOWN;
  676.  
  677.           /* Init scroller down arrow gadget */
  678.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  679.                                      buffer;
  680.           buffer += sizeof(struct ExtendedGadget);
  681.           buffer  = init_extended_gadget(egad, buffer, gl, gd, i,
  682.                   EXTENDED_GADGET_TYPE_SCROLLER_DOWN, left_edge,
  683.                      top_edge + height - ymin, width, ymin);
  684.           /* Change type of vertical scroller arrow gadget for correct counting */
  685.           egad->eg_Type = EXTENDED_GADGET_TYPE_SCROLLER_UP;
  686.            } else {
  687.  
  688.           /* Create horizontal scroller - prop gadget first */
  689.           buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  690.                   EXTENDED_GADGET_TYPE_SCROLLER_PROP, left_edge,
  691.                   top_edge, width - 2 * (xmin + 1), height);
  692.           /* Init scroller left arrow gadget */
  693.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  694.                                      buffer;
  695.           buffer += sizeof(struct ExtendedGadget);
  696.           buffer  = init_extended_gadget(egad, buffer, gl, gd, i,
  697.                  EXTENDED_GADGET_TYPE_SCROLLER_LEFT, left_edge +
  698.                   width - 2 * xmin - 1, top_edge, xmin, height);
  699.           /* Init scroller right arrow gadget */
  700.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  701.                                      buffer;
  702.           buffer += sizeof(struct ExtendedGadget);
  703.           buffer  = init_extended_gadget(egad, buffer, gl, gd, i,
  704.                 EXTENDED_GADGET_TYPE_SCROLLER_RIGHT, left_edge +
  705.                       width - xmin, top_edge, xmin, height);
  706.            }
  707.         }
  708.         break;
  709.  
  710.      case GADGET_DATA_TYPE_CYCLE :
  711.  
  712.         /* Count entries and calc max width of cycle text array */
  713.                text = gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray;
  714.         num  = max_width = 0;
  715.         while (*text) {
  716.            itext.IText = (UBYTE *)get_language_text(*text++,
  717.                           gl->gl_LanguageTextArray);
  718.            if ((len = IntuiTextLength(&itext)) > max_width) {
  719.           max_width = len;
  720.            }
  721.            num++;
  722.         }
  723.  
  724.         /* Init cycle data */
  725.         image              = &ri->ri_Images[IMAGE_CYCLE];
  726.         xmin               = image->LeftEdge + image->Width +
  727.                                 xoffset + 4;
  728.         cy->cy_LeftEdge    = left_edge + xmin + (SHORT)(width -
  729.                           max_width - xmin - 4) / 2;
  730.         cy->cy_TopEdge     = top_edge + (SHORT)(height - text_height) / 2;
  731.         cy->cy_Width       = max_width;
  732.         cy->cy_Height      = text_height;
  733.         cy->cy_EntryHeight = text_height +
  734.                 gd->gd_SpecialData.gd_CycleData.gd_CycleSpacing;
  735.         cy->cy_TextArray   = gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray;
  736.         cy->cy_TextEntries = num;
  737.         buffer             = init_extended_gadget(egad, buffer, gl, gd,
  738.           i, EXTENDED_GADGET_TYPE_CYCLE, left_edge, top_edge, width,
  739.                                     height);
  740.         break;
  741.  
  742.      case GADGET_DATA_TYPE_COUNT :
  743.  
  744.         /* Calc max width of count value */
  745.         min = gd->gd_SpecialData.gd_CountData.gd_CountMin;
  746.         max = gd->gd_SpecialData.gd_CountData.gd_CountMax;
  747.         if (flags & GADGET_DATA_FLAG_COUNT_SIGNED_DEC) {
  748.            len       = convert_signed_dec((LONG)min, (BYTE *)NULL, 0);
  749.            max_width = convert_signed_dec((LONG)max, (BYTE *)NULL, 0);
  750.         } else {
  751.            len       = convert_unsigned_dec(min, (BYTE *)NULL, 0);
  752.            max_width = convert_unsigned_dec(max, (BYTE *)NULL, 0);
  753.         }
  754.         if (len > max_width) {
  755.            max_width = len;
  756.         }
  757.         itext.IText = (UBYTE *)"8";
  758.         max_width  *= IntuiTextLength(&itext);
  759.  
  760.         /* Init count data */
  761.         co->co_LeftEdge = left_edge + (SHORT)(width - max_width) / 2;
  762.         co->co_TopEdge  = top_edge + (SHORT)(height - text_height) / 2;
  763.         co->co_Width    = max_width;
  764.         co->co_Height   = text_height;
  765.         co->co_Min      = min;
  766.         co->co_Max      = max;
  767.         buffer          = init_extended_gadget(egad, buffer, gl, gd, i,
  768.              EXTENDED_GADGET_TYPE_COUNT, left_edge, top_edge, width,
  769.                                     height);
  770.         break;
  771.  
  772.      case GADGET_DATA_TYPE_LISTVIEW :
  773.  
  774.         /* Init list view data */
  775.         lv->lv_LeftEdge       = left_edge + xoffset;
  776.         lv->lv_TopEdge        = top_edge + yoffset;
  777.         lv->lv_Width          = width - 2 * xoffset - xmin - 2;
  778.         lv->lv_Height         = height - 2 * yoffset;
  779.         lv->lv_VisibleEntries = num;
  780.         lv->lv_EntryHeight    = yinc;
  781.  
  782.         /* Create vertical scroller - prop gadget first */
  783.         left_edge += width - xmin;
  784.         buffer     = init_extended_gadget(egad, buffer, gl, gd, i,
  785.             EXTENDED_GADGET_TYPE_LISTVIEW_PROP, left_edge, top_edge,
  786.                          xmin, height - 2 * (ymin + 1));
  787.         /* Create entry field border */
  788.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  789.            USHORT border_type;
  790.  
  791.            ((struct Border *)egad->eg_Render)->NextBorder->NextBorder =
  792.                             (struct Border *)buffer;
  793.            if (flags & GADGET_DATA_FLAG_LISTVIEW_READ_ONLY) {
  794.           border_type = BORDER_DATA_TYPE_BOX1_IN;
  795.            } else {
  796.           border_type = BORDER_DATA_TYPE_BOX1_OUT;
  797.            }
  798.            buffer = init_border(ri, buffer, -(width + xoffset - xmin),
  799.                -yoffset, width - xmin - 2, height, border_type);
  800.         }
  801.  
  802.         /* Init list view up arrow gadget */
  803.         egad    = egad->eg_NextGadget = (struct ExtendedGadget *)buffer;
  804.         buffer += sizeof(struct ExtendedGadget);
  805.         buffer  = init_extended_gadget(egad, buffer, gl, gd, i,
  806.              EXTENDED_GADGET_TYPE_LISTVIEW_UP, left_edge, top_edge +
  807.                      height - 2 * ymin - 1, xmin, ymin);
  808.         /* Init list view down arrow gadget */
  809.         egad    = egad->eg_NextGadget = (struct ExtendedGadget *)buffer;
  810.         buffer += sizeof(struct ExtendedGadget);
  811.         buffer  = init_extended_gadget(egad, buffer, gl, gd, i,
  812.            EXTENDED_GADGET_TYPE_LISTVIEW_DOWN, left_edge, top_edge +
  813.                          height - ymin, xmin, ymin);
  814.         /* Init list view entry gadgets */
  815.         if (!(flags & GADGET_DATA_FLAG_LISTVIEW_READ_ONLY)) {
  816.            left_edge = lv->lv_LeftEdge;
  817.            top_edge  = lv->lv_TopEdge;
  818.            for (j = 0; j < num; j++, top_edge += yinc) {
  819.           egad            = egad->eg_NextGadget =
  820.                         (struct ExtendedGadget *)buffer;
  821.           buffer         += sizeof(struct ExtendedGadget);
  822.           buffer          = init_extended_gadget(egad, buffer, gl,
  823.                  gd, i, EXTENDED_GADGET_TYPE_LISTVIEW_ENTRY,
  824.                    left_edge, top_edge, lv->lv_Width, yinc);
  825.           egad->eg_Gadget.GadgetID = j;   /* num of entry gadget */
  826.            }
  827.         }
  828.         break;
  829.  
  830.      case GADGET_DATA_TYPE_PALETTE :
  831.  
  832.         /* Init palette data */
  833.         pd->pd_ColorOffset = min;
  834.         pd->pd_MaxColors   = max;
  835.  
  836.         /* Build color indicator */
  837.         if (!(flags & GADGET_DATA_FLAG_PALETTE_NO_INDICATOR)) {
  838.            if (flags & GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP) {
  839.           buffer    = init_extended_gadget(egad, buffer, gl, gd, i,
  840.               EXTENDED_GADGET_TYPE_PALETTE_INDICATOR, left_edge,
  841.                              top_edge, width, ymin);
  842.           top_edge += ymin + 1;
  843.           ynum--;
  844.            } else {
  845.           buffer     = init_extended_gadget(egad, buffer, gl, gd, i,
  846.               EXTENDED_GADGET_TYPE_PALETTE_INDICATOR, left_edge,
  847.                             top_edge, xmin, height);
  848.           left_edge += xmin + 2;
  849.           xnum--;
  850.            }
  851.            egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  852.                                      buffer;
  853.            buffer += sizeof(struct ExtendedGadget);
  854.         }
  855.  
  856.         /* Build color gadgets */
  857.         num = gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset;
  858.         for (j = 0; j < ynum; j++, top_edge += ymin + 1) {
  859.            USHORT k, temp_left_edge = left_edge;
  860.  
  861.            for (k = 0; k < xnum; k++, temp_left_edge += xmin + 2) {
  862.           buffer = init_extended_gadget(egad, buffer, gl, gd, i,
  863.              EXTENDED_GADGET_TYPE_PALETTE_COLOR, temp_left_edge,
  864.                               top_edge, xmin, ymin);
  865.           ((struct Image *)egad->eg_Render)->PlaneOnOff =
  866.                        egad->eg_Gadget.GadgetID = num++;
  867.           if (j < (ynum - 1) || k < (xnum - 1)) {
  868.              egad    = egad->eg_NextGadget =
  869.                         (struct ExtendedGadget *)buffer;
  870.              buffer += sizeof(struct ExtendedGadget);
  871.           }
  872.            }
  873.         }
  874.         break;
  875.       }
  876.  
  877.       /* Save absolut gadget dimension - needed by editor */
  878.       first_egad->eg_BorderWidth  = width;
  879.       first_egad->eg_BorderHeight = height;
  880.  
  881.       /* Init text */
  882.       if (gd->gd_Text) {
  883.      init_gadget_text(first_egad, get_language_text(gd->gd_Text,
  884.                gl->gl_LanguageTextArray), width, height, flags, ta);
  885.       }
  886.  
  887.       /* Init images */
  888.       if (image_buffer) {
  889.      switch (type) {
  890.         case GADGET_DATA_TYPE_BUTTON :
  891.            if (flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  892.           image_buffer = init_image_data(egad, image_buffer);
  893.            }
  894.            break;
  895.  
  896.         case GADGET_DATA_TYPE_SLIDER :
  897.            if (flags & GADGET_DATA_FLAG_SLIDER_IMAGE) {
  898.           image_buffer = init_image_data(egad, image_buffer);
  899.            }
  900.            break;
  901.      }
  902.       }
  903.  
  904.       /* Finally set gadget flags and special data */
  905.       set_gadget_attributes(gl, i, 0xffffffffL, flags,
  906.                     gd->gd_SpecialData.gd_Data.gd_Data1,
  907.                     gd->gd_SpecialData.gd_Data.gd_Data2,
  908.                        gd->gd_SpecialData.gd_Data.gd_Data3);
  909.    }
  910. }
  911.     /* Init extended gadget */
  912.  
  913.    STATIC BYTE *
  914. init_extended_gadget(struct ExtendedGadget  *egad, BYTE *buffer,
  915.       struct GadgetList  *gl, struct GadgetData  *gd, USHORT data_entry,
  916.            USHORT type, USHORT left_edge, USHORT top_edge, USHORT width,
  917.                                   USHORT height)
  918. {
  919.    struct RenderInfo  *ri = gl->gl_RenderInfo;
  920.    struct Gadget      *gad = &egad->eg_Gadget;
  921.    struct StringInfo  *sinfo;
  922.    struct PropInfo    *pinfo;
  923.    struct Image       *image;
  924.    ULONG  flags = gd->gd_Flags;
  925.    USHORT len;
  926.  
  927.    /* If monochrome display then set HIGHCOMP flag */
  928.    if (ri->ri_ScreenDepth == 1) {
  929.       flags |= GADGET_DATA_FLAG_HIGH_COMP;
  930.    }
  931.  
  932.    /* Init extended gadget */
  933.    egad->eg_Type       = type;
  934.    egad->eg_Flags      = 0;
  935.    egad->eg_DataType   = gd->gd_Type;
  936.    egad->eg_DataEntry  = data_entry;
  937.    egad->eg_DataFlags  = flags;
  938.    egad->eg_GadgetList = gl;
  939.  
  940.    /* Init normal gadget */
  941.    gad->LeftEdge      = left_edge;
  942.    gad->TopEdge       = top_edge;
  943.    gad->Width         = width;
  944.    gad->Height        = height;
  945.    gad->MutualExclude = ISUP_ID;
  946.    switch (type) {
  947.       case EXTENDED_GADGET_TYPE_BUTTON :
  948.      gad->GadgetType = BOOLGADGET;
  949.      if (flags & GADGET_DATA_FLAG_BUTTON_TOGGLE) {
  950.         gad->Activation = RELVERIFY | TOGGLESELECT;
  951.         if (flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  952.            gad->Flags = GADGIMAGE | GADGHIMAGE;
  953.            buffer     = init_button_image(egad, gd, buffer);
  954.         }
  955.      } else {
  956.         gad->Activation = RELVERIFY;
  957.         if (flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  958.            if ((flags & GADGET_DATA_FLAG_NO_BORDER) &&
  959.                     !(flags & GADGET_DATA_FLAG_HIGH_COMP)) {
  960.           gad->Flags = GADGIMAGE | GADGHIMAGE;
  961.           buffer     = init_button_image(egad, gd, buffer);
  962.            } else {
  963.           buffer          = init_button_image(egad, gd, buffer);
  964.           egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  965.            }
  966.         }
  967.      }
  968.      break;
  969.  
  970.       case EXTENDED_GADGET_TYPE_CHECK :
  971.       case EXTENDED_GADGET_TYPE_MX :
  972.      gad->GadgetType = BOOLGADGET;
  973.      gad->Activation = TOGGLESELECT | GADGIMMEDIATE;
  974.      gad->Flags      = GADGIMAGE | GADGHIMAGE;
  975.      if (type == EXTENDED_GADGET_TYPE_CHECK) {
  976.         gad->GadgetRender = (APTR)&ri->ri_Images[IMAGE_CHECK_UNSELECTED];
  977.         gad->SelectRender = (APTR)&ri->ri_Images[IMAGE_CHECK_SELECTED];
  978.      } else {
  979.         gad->GadgetRender = (APTR)&ri->ri_Images[IMAGE_KNOB_UNSELECTED];
  980.         gad->SelectRender = (APTR)&ri->ri_Images[IMAGE_KNOB_SELECTED];
  981.      }
  982.      break;
  983.  
  984.       case EXTENDED_GADGET_TYPE_STRING :
  985.       case EXTENDED_GADGET_TYPE_INTEGER :
  986.      gad->GadgetType = STRGADGET;
  987.      if (type == EXTENDED_GADGET_TYPE_STRING) {
  988.         gad->Activation = RELVERIFY;
  989.      } else {
  990.         gad->Activation = RELVERIFY | LONGINT;
  991.      }
  992.      if (flags & GADGET_DATA_FLAG_INPUT_CENTER) {
  993.         gad->Activation |= STRINGCENTER;
  994.      } else {
  995.         if (flags & GADGET_DATA_FLAG_INPUT_RIGHT) {
  996.            gad->Activation |= STRINGRIGHT;
  997.         }
  998.      }
  999.      gad->Flags       = GADGHCOMP;
  1000.      gad->SpecialInfo = (APTR)buffer;
  1001.  
  1002.      /* Calc size of input buffer */
  1003.      if (type == GADGET_DATA_TYPE_STRING) {
  1004.         len = gd->gd_SpecialData.gd_InputData.gd_InputLen;
  1005.         if (flags & (GADGET_DATA_FLAG_STRING_UNSIGNED_DEC |
  1006.                     GADGET_DATA_FLAG_STRING_SIGNED_DEC |
  1007.                            GADGET_DATA_FLAG_STRING_HEX |
  1008.                          GADGET_DATA_FLAG_STRING_BIN)) {
  1009.            if (len < (MAX_BIN_NUM_DIGITS + 1)) {
  1010.           len = MAX_BIN_NUM_DIGITS + 1;   /* identifier `%' + number */
  1011.            }
  1012.         }
  1013.      } else {
  1014.         len = MAX_DEC_NUM_DIGITS;
  1015.      }
  1016.  
  1017.      /* Init string info */
  1018.      sinfo           = (struct StringInfo *)buffer;
  1019.      buffer         += sizeof(struct StringInfo);
  1020.      sinfo->Buffer   = (UBYTE *)buffer;
  1021.      sinfo->MaxChars = len + 1;
  1022.      if (len & 1) {   /* input len odd */
  1023.         buffer += len + 1;
  1024.      } else {
  1025.         buffer += len + 2;
  1026.      }
  1027.      break;
  1028.  
  1029.       case EXTENDED_GADGET_TYPE_SLIDER_PROP :
  1030.       case EXTENDED_GADGET_TYPE_SCROLLER_PROP :
  1031.       case EXTENDED_GADGET_TYPE_LISTVIEW_PROP :
  1032.      gad->GadgetType   = PROPGADGET;
  1033.      gad->Activation   = GADGIMMEDIATE | RELVERIFY | FOLLOWMOUSE;
  1034.      if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  1035.         gad->Flags = GADGHCOMP;
  1036.      } else {
  1037.         gad->Flags = GADGHNONE;
  1038.      }
  1039.      gad->GadgetRender = (APTR)buffer;   /* needed for auto knob */
  1040.      buffer           += sizeof(struct Image);
  1041.      gad->SpecialInfo  = (APTR)buffer;
  1042.  
  1043.      /* Init prop info */
  1044.      pinfo   = (struct PropInfo *)buffer;
  1045.      buffer += sizeof(struct PropInfo);
  1046.      if (type == EXTENDED_GADGET_TYPE_SLIDER_PROP &&
  1047.            (flags & GADGET_DATA_FLAG_SLIDER_IMAGE) && gd->gd_TextAttr) {
  1048.         pinfo->Flags = PROPBORDERLESS;
  1049.         CopyMem((BYTE *)gd->gd_TextAttr, (BYTE *)gad->GadgetRender,
  1050.                         (LONG)sizeof(struct Image));
  1051.         egad->eg_Flags |= EXTENDED_GADGET_FLAG_KNOB_IMAGE;
  1052.      } else {
  1053.         pinfo->Flags = AUTOKNOB | PROPBORDERLESS;
  1054.      }
  1055.      if (type == EXTENDED_GADGET_TYPE_LISTVIEW_PROP || (flags &
  1056.                        GADGET_DATA_FLAG_ORIENTATION_VERT)) {
  1057.         pinfo->Flags |= FREEVERT;
  1058.      } else {
  1059.         pinfo->Flags |= FREEHORIZ;
  1060.      }
  1061.      break;
  1062.  
  1063.       case EXTENDED_GADGET_TYPE_SCROLLER_LEFT :
  1064.       case EXTENDED_GADGET_TYPE_SCROLLER_RIGHT :
  1065.       case EXTENDED_GADGET_TYPE_SCROLLER_UP :
  1066.       case EXTENDED_GADGET_TYPE_SCROLLER_DOWN :
  1067.       case EXTENDED_GADGET_TYPE_LISTVIEW_UP :
  1068.       case EXTENDED_GADGET_TYPE_LISTVIEW_DOWN :
  1069.      gad->GadgetType = BOOLGADGET;
  1070.      gad->Activation = GADGIMMEDIATE | RELVERIFY;
  1071.      switch (type) {
  1072.         case EXTENDED_GADGET_TYPE_SCROLLER_LEFT :
  1073.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_LEFT];
  1074.            break;
  1075.  
  1076.         case EXTENDED_GADGET_TYPE_SCROLLER_RIGHT :
  1077.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_RIGHT];
  1078.            break;
  1079.  
  1080.         case EXTENDED_GADGET_TYPE_SCROLLER_UP :
  1081.         case EXTENDED_GADGET_TYPE_LISTVIEW_UP :
  1082.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_UP];
  1083.            break;
  1084.  
  1085.         case EXTENDED_GADGET_TYPE_SCROLLER_DOWN :
  1086.         case EXTENDED_GADGET_TYPE_LISTVIEW_DOWN :
  1087.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_DOWN];
  1088.            break;
  1089.      }
  1090.      egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  1091.      break;
  1092.  
  1093.       case EXTENDED_GADGET_TYPE_CYCLE :
  1094.      gad->GadgetType = BOOLGADGET;
  1095.      gad->Activation = TOGGLESELECT | GADGIMMEDIATE;
  1096.      egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_CYCLE];
  1097.      egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  1098.      break;
  1099.  
  1100.       case EXTENDED_GADGET_TYPE_COUNT :
  1101.      gad->GadgetType = BOOLGADGET;
  1102.      gad->Activation = TOGGLESELECT | GADGIMMEDIATE;
  1103.      egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_COUNT_LEFT];
  1104.      egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  1105.      break;
  1106.  
  1107.       case EXTENDED_GADGET_TYPE_LISTVIEW_ENTRY :
  1108.      gad->GadgetType = BOOLGADGET;
  1109.      gad->Activation = RELVERIFY;
  1110.      gad->Flags      = GADGHCOMP;
  1111.      break;
  1112.  
  1113.       case EXTENDED_GADGET_TYPE_PALETTE_INDICATOR :
  1114.       case EXTENDED_GADGET_TYPE_PALETTE_COLOR :
  1115.      gad->GadgetType = BOOLGADGET;
  1116.      gad->Activation = RELVERIFY;
  1117.  
  1118.      /* Init image */
  1119.      image   = (struct Image *)buffer;
  1120.      buffer += sizeof(struct Image);
  1121.      if (flags & GADGET_DATA_FLAG_NO_BORDER) {
  1122.         image->Width  = width;
  1123.         image->Height = height;
  1124.      } else {
  1125.         image->Width  = width - 2 * 4;
  1126.         image->Height = height - 2 * 2;
  1127.      }
  1128.      image->Depth    = ri->ri_ScreenDepth;
  1129.      egad->eg_Render = (APTR)image;
  1130.      egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  1131.      break;
  1132.    }
  1133.    if (flags & GADGET_DATA_FLAG_DISABLED) {
  1134.       gad->Flags |= GADGDISABLED;
  1135.    }
  1136.    return(init_gadget_border(buffer, ri, egad, flags));
  1137. }
  1138.     /* Init gadget border */
  1139.  
  1140.    STATIC BYTE *
  1141. init_gadget_border(BYTE *buffer, struct RenderInfo  *ri,
  1142.                   struct ExtendedGadget  *egad, ULONG flags)
  1143. {
  1144.    struct Gadget  *gad = &egad->eg_Gadget;
  1145.    USHORT width = gad->Width, height = gad->Height;
  1146.  
  1147.    switch (egad->eg_Type) {
  1148.       case EXTENDED_GADGET_TYPE_BUTTON :
  1149.      if ((flags & GADGET_DATA_FLAG_BUTTON_TOGGLE) &&
  1150.                   (flags & GADGET_DATA_FLAG_BUTTON_IMAGE)) {
  1151.         /* Init non toggle border out */
  1152.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1153.            egad->eg_Render = (APTR)buffer;
  1154.            egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_BORDER;
  1155.            buffer          = init_border(ri, buffer, 0, 0, width,
  1156.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  1157.         }
  1158.      } else {
  1159.  
  1160.         /* Init toggle border */
  1161.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  1162.            gad->Flags |= GADGHCOMP;
  1163.            if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1164.           gad->GadgetRender = (APTR)buffer;
  1165.           buffer            = init_border(ri, buffer, 0, 0, width,
  1166.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  1167.            }
  1168.         } else {
  1169.            if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1170.           gad->Flags       |= GADGHIMAGE;
  1171.           gad->GadgetRender = (APTR)buffer;
  1172.           buffer            = init_border(ri, buffer, 0, 0, width,
  1173.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  1174.           gad->SelectRender = (APTR)buffer;
  1175.           buffer            = init_border(ri, buffer, 0, 0, width,
  1176.                       height, BORDER_DATA_TYPE_BOX1_IN);
  1177.            } else {
  1178.           if (!(gad->Flags & GADGHIMAGE)) {
  1179.              gad->Flags |= GADGHNONE;
  1180.           }
  1181.            }
  1182.         }
  1183.      }
  1184.      break;
  1185.  
  1186.       case EXTENDED_GADGET_TYPE_CHECK :
  1187.  
  1188.      /* Init non toggle border out */
  1189.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1190.         egad->eg_Render = (APTR)buffer;
  1191.         egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_BORDER;
  1192.         buffer          = init_border(ri, buffer, 0, 0, width, height,
  1193.                          BORDER_DATA_TYPE_BOX1_OUT);
  1194.      }
  1195.      break;
  1196.  
  1197.       case EXTENDED_GADGET_TYPE_SCROLLER_LEFT :
  1198.       case EXTENDED_GADGET_TYPE_SCROLLER_RIGHT :
  1199.       case EXTENDED_GADGET_TYPE_SCROLLER_UP :
  1200.       case EXTENDED_GADGET_TYPE_SCROLLER_DOWN :
  1201.       case EXTENDED_GADGET_TYPE_LISTVIEW_UP :
  1202.       case EXTENDED_GADGET_TYPE_LISTVIEW_DOWN :
  1203.       case EXTENDED_GADGET_TYPE_CYCLE :
  1204.       case EXTENDED_GADGET_TYPE_COUNT :
  1205.       case EXTENDED_GADGET_TYPE_PALETTE_COLOR :
  1206.  
  1207.      /* Init toggle border */
  1208.      if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  1209.         gad->Flags |= GADGHCOMP;
  1210.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1211.            gad->GadgetRender = (APTR)buffer;
  1212.            buffer            = init_border(ri, buffer, 0, 0,
  1213.                   width, height, BORDER_DATA_TYPE_BOX1_OUT);
  1214.         }
  1215.      } else {
  1216.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1217.            gad->Flags       |= GADGHIMAGE;
  1218.            gad->GadgetRender = (APTR)buffer;
  1219.            buffer            = init_border(ri, buffer, 0, 0, width,
  1220.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  1221.            gad->SelectRender = (APTR)buffer;
  1222.            buffer            = init_border(ri, buffer, 0, 0, width,
  1223.                       height, BORDER_DATA_TYPE_BOX1_IN);
  1224.         } else {
  1225.            gad->Flags |= GADGHNONE;
  1226.         }
  1227.      }
  1228.      break;
  1229.  
  1230.       case EXTENDED_GADGET_TYPE_PALETTE_INDICATOR :
  1231.  
  1232.      /* Init non toggle border in */
  1233.      gad->Flags |= GADGHNONE;
  1234.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1235.         gad->GadgetRender = (APTR)buffer;
  1236.         buffer            = init_border(ri, buffer, 0, 0, width, height,
  1237.                           BORDER_DATA_TYPE_BOX1_IN);
  1238.      }
  1239.      break;
  1240.  
  1241.       case EXTENDED_GADGET_TYPE_STRING :
  1242.       case EXTENDED_GADGET_TYPE_INTEGER :
  1243.  
  1244.      /* Init input border */
  1245.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1246.         gad->GadgetRender = (APTR)buffer;
  1247.         gad->LeftEdge    += 6;
  1248.         gad->TopEdge     += 3;
  1249.         gad->Width       -= 2 * 6;
  1250.         gad->Height      -= 2 * 3;
  1251.         buffer            = init_border(ri, buffer, -6, -3, width,
  1252.                      height, BORDER_DATA_TYPE_BOX2_OUT);
  1253.      }
  1254.      break;
  1255.  
  1256.       case EXTENDED_GADGET_TYPE_SLIDER_PROP :
  1257.       case EXTENDED_GADGET_TYPE_SCROLLER_PROP :
  1258.       case EXTENDED_GADGET_TYPE_LISTVIEW_PROP :
  1259.  
  1260.      /* Init prop border */
  1261.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1262.         egad->eg_Render = (APTR)buffer;
  1263.         egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_BORDER;
  1264.         gad->LeftEdge  += 4;
  1265.         gad->TopEdge   += 2;
  1266.         gad->Width     -= 2 * 4;
  1267.         gad->Height    -= 2 * 2;
  1268.         buffer          = init_border(ri, buffer, -4, -2, width, height,
  1269.                          BORDER_DATA_TYPE_BOX1_OUT);
  1270.      }
  1271.      break;
  1272.    }
  1273.    return(buffer);
  1274. }
  1275.     /* Init gadget text */
  1276.  
  1277.    STATIC VOID
  1278. init_gadget_text(struct ExtendedGadget  *egad, BYTE *text, USHORT width,
  1279.                USHORT height, ULONG flags, struct TextAttr  *ta)
  1280. {
  1281.    /* Search hotkey in gadget text */
  1282.    if (flags & GADGET_DATA_FLAG_HOTKEY) {
  1283.       BYTE   *ptr = text;
  1284.       USHORT i;
  1285.  
  1286.       for (i = 0; *ptr; i++) {
  1287.      BYTE c;
  1288.  
  1289.      if (*ptr++ == '_' && (c = *ptr)) {
  1290.  
  1291.         /* Only printable characters are allowed as hotkeys */
  1292.         c = tolower(c);
  1293.         if (c >= ' ' && c <= '~') {
  1294.            egad->eg_Hotkey    = (USHORT)c;
  1295.            egad->eg_HotkeyPos = i + 1;
  1296.            egad->eg_Flags    |= EXTENDED_GADGET_FLAG_HOTKEY;
  1297.            break;
  1298.         }
  1299.      }
  1300.       }
  1301.    }
  1302.  
  1303.    /* Ignore text if no output is required */
  1304.    if (!(flags & GADGET_DATA_FLAG_NO_TEXT_OUTPUT)) {
  1305.       struct IntuiText  itext;
  1306.       SHORT  text_width, text_height, xoffset, yoffset, left_edge, top_edge;
  1307.       USHORT type = egad->eg_DataType;
  1308.  
  1309.       /* Calc text dimension */
  1310.       itext.IText     = (UBYTE *)text;
  1311.       itext.ITextFont = ta;
  1312.       text_width      = IntuiTextLength(&itext);
  1313.       if (egad->eg_Flags & EXTENDED_GADGET_FLAG_HOTKEY) {
  1314.      itext.IText = (UBYTE *)&hotkey_id[0];
  1315.      text_width -= IntuiTextLength(&itext);
  1316.       }
  1317.       text_height = ta->ta_YSize;
  1318.  
  1319.       /* Calc border offset */
  1320.       if (flags & GADGET_DATA_FLAG_NO_BORDER) {
  1321.      xoffset = 0;
  1322.      yoffset = 0;
  1323.       } else {
  1324.      switch (type) {
  1325.         case GADGET_DATA_TYPE_MX :
  1326.            xoffset = 8;
  1327.            yoffset = 4;
  1328.            break;
  1329.  
  1330.         case GADGET_DATA_TYPE_STRING :
  1331.         case GADGET_DATA_TYPE_INTEGER :
  1332.            xoffset = 6;
  1333.            yoffset = 3;
  1334.            break;
  1335.  
  1336.         case GADGET_DATA_TYPE_SLIDER :
  1337.         case GADGET_DATA_TYPE_SCROLLER :
  1338.         case GADGET_DATA_TYPE_LISTVIEW :
  1339.            xoffset = 4;
  1340.            yoffset = 2;
  1341.            break;
  1342.  
  1343.         default :
  1344.            xoffset = 0;
  1345.            yoffset = 0;
  1346.            break;
  1347.      }
  1348.       }
  1349.  
  1350.       /* Calc text pos */
  1351.       switch (type) {
  1352.      case GADGET_DATA_TYPE_MX :
  1353.         if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  1354.            left_edge = -(width - egad->eg_Gadget.Width - xoffset -
  1355.                        (SHORT)(width - text_width) / 2);
  1356.         } else {
  1357.            left_edge = (SHORT)(width - text_width) / 2 - xoffset;
  1358.         }
  1359.         if (text_height > IMAGE_KNOB_HEIGHT) {
  1360.            top_edge = -((text_height - IMAGE_KNOB_HEIGHT) / 2);
  1361.         } else {
  1362.            top_edge = 0;
  1363.         }
  1364.         top_edge -= (text_height + yoffset + 4);
  1365.         break;
  1366.  
  1367.      case GADGET_DATA_TYPE_LISTVIEW :
  1368.         left_edge = -(width - egad->eg_Gadget.Width - xoffset -
  1369.                        (SHORT)(width - text_width) / 2);
  1370.         top_edge  = -(text_height + yoffset + 4);
  1371.         break;
  1372.  
  1373.      case GADGET_DATA_TYPE_PALETTE :
  1374.         left_edge = (SHORT)(width - text_width) / 2;
  1375.         top_edge  = -(text_height + 4);
  1376.         break;
  1377.  
  1378.      default :
  1379.  
  1380.         /* Calc horizontal pos */
  1381.         if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  1382.            left_edge = -(text_width + xoffset + 8);
  1383.         } else {
  1384.            if (flags & GADGET_DATA_FLAG_TEXT_RIGHT) {
  1385.           left_edge = width - xoffset + 8;
  1386.            } else {
  1387.           left_edge = (SHORT)(width - 2 * xoffset - text_width) / 2;
  1388.            }
  1389.         }
  1390.  
  1391.         /* Calc vertical pos */
  1392.         if (flags & GADGET_DATA_FLAG_TEXT_ABOVE) {
  1393.            top_edge = -(text_height + yoffset + 4);
  1394.         } else {
  1395.            if (flags & GADGET_DATA_FLAG_TEXT_BELOW) {
  1396.           top_edge = height - yoffset + 4;
  1397.            } else {
  1398.           top_edge = (SHORT)(height - 2 * yoffset - text_height) / 2;
  1399.            }
  1400.         }
  1401.         break;
  1402.       }
  1403.  
  1404.       /* Save position and width of text */
  1405.       egad->eg_Text         = text;
  1406.       egad->eg_TextLeftEdge = left_edge;
  1407.       egad->eg_TextTopEdge  = top_edge;
  1408.       egad->eg_TextWidth    = text_width;
  1409.    }
  1410. }
  1411.     /* Init mutual exclude gadget text */
  1412.  
  1413.    STATIC BYTE *
  1414. init_mx_text(struct ExtendedGadget  *egad, BYTE *buffer, BYTE *text,
  1415.          USHORT width, USHORT height, ULONG flags, struct TextAttr  *ta)
  1416. {
  1417.    struct RenderInfo  *ri = egad->eg_GadgetList->gl_RenderInfo;
  1418.    struct IntuiText   *itext;
  1419.  
  1420.    itext            = (struct IntuiText *)buffer;
  1421.    buffer          += sizeof(struct IntuiText);
  1422.    itext->FrontPen  = (flags & GADGET_DATA_FLAG_TEXT_COLOR2 ?
  1423.                      ri->ri_TextPen2 : ri->ri_TextPen1);
  1424.    itext->BackPen   = ri->ri_BackPen;
  1425.    itext->DrawMode  = JAM2;
  1426.    itext->IText     = (UBYTE *)text;
  1427.    itext->ITextFont = ta;
  1428.    itext->TopEdge   = (SHORT)(height - ta->ta_YSize) / 2;
  1429.    if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  1430.       itext->LeftEdge = -(IntuiTextLength(itext) + 8);
  1431.    } else {
  1432.       itext->LeftEdge = width + 8;   /* default right */
  1433.    }
  1434.    egad->eg_Gadget.GadgetText = itext;
  1435.    return(buffer);
  1436. }
  1437.     /* Check image for valid chip mem data */
  1438.  
  1439.    STATIC BOOL
  1440. check_gadget_image(struct Image  *image)
  1441. {
  1442.    BYTE *data;
  1443.    BOOL result;
  1444.  
  1445.    if (image && (data = (BYTE *)image->ImageData) &&
  1446.                        !(TypeOfMem(data) & MEMF_CHIP)) {
  1447.       result = FALSE;
  1448.    } else {
  1449.       result = TRUE;
  1450.    }
  1451.    return(result);
  1452. }
  1453.     /* Init image of button gadget */
  1454.  
  1455.    STATIC BYTE *
  1456. init_button_image(struct ExtendedGadget  *egad, struct GadgetData  *gd,
  1457.                                    BYTE *buffer)
  1458. {
  1459.    struct Gadget  *gad = &egad->eg_Gadget;
  1460.    struct Image   *image = gd->gd_SpecialData.gd_ButtonData.
  1461.                               gd_ButtonNormalRender;
  1462.    if (gad->Flags & GADGIMAGE) {
  1463.       if (check_gadget_image(image) == FALSE) {
  1464.      CopyMem((BYTE *)image, buffer, (LONG)sizeof(struct Image));
  1465.      image   = (struct Image *)buffer;
  1466.      buffer += sizeof(struct Image);
  1467.       }
  1468.       gad->GadgetRender = (APTR)image;
  1469.       if (gad->Flags & GADGHIMAGE) {
  1470.      if (!(image = gd->gd_SpecialData.gd_ButtonData.
  1471.                            gd_ButtonSelectRender)) {
  1472.         gad->Flags &= ~GADGHIGHBITS;
  1473.         gad->Flags |= GADGHNONE;
  1474.      } else {
  1475.         if (check_gadget_image(image) == FALSE) {
  1476.            CopyMem((BYTE *)image, buffer, (LONG)sizeof(struct Image));
  1477.            image   = (struct Image *)buffer;
  1478.            buffer += sizeof(struct Image);
  1479.         }
  1480.         gad->SelectRender = (APTR)image;
  1481.      }
  1482.       }
  1483.    } else {
  1484.       if (check_gadget_image(image) == FALSE) {
  1485.      CopyMem((BYTE *)image, buffer, (LONG)sizeof(struct Image));
  1486.      image   = (struct Image *)buffer;
  1487.      buffer += sizeof(struct Image);
  1488.       }
  1489.       egad->eg_Render = (APTR)image;
  1490.    }
  1491.    return(buffer);
  1492. }
  1493.     /* Init image data - make chipmem copy if needed */
  1494.  
  1495.    STATIC BYTE *
  1496. init_image_data(struct ExtendedGadget  *egad, BYTE *buffer)
  1497. {
  1498.    struct Gadget  *gad = &egad->eg_Gadget;
  1499.    struct Image   *image;
  1500.    LONG  size;
  1501.    BYTE  *data;
  1502.    UBYTE flags = egad->eg_Flags;
  1503.  
  1504.    switch (egad->eg_Type) {
  1505.       case EXTENDED_GADGET_TYPE_BUTTON :
  1506.  
  1507.      /* Check normal button image */
  1508.      if (flags & EXTENDED_GADGET_FLAG_RENDER_IMAGE) {
  1509.         image = (struct Image *)egad->eg_Render;
  1510.      } else {
  1511.         image = (struct Image *)gad->GadgetRender;
  1512.      }
  1513.      if ((data = (BYTE *)image->ImageData) &&
  1514.                        !(TypeOfMem(data) & MEMF_CHIP)) {
  1515.         size = (image->Width / 16 + (image->Width & 15 ? 1 : 0))
  1516.                      * image->Height * image->Depth * 2;
  1517.         CopyMem(data, buffer, size);
  1518.         image->ImageData = (UWORD *)buffer;
  1519.         buffer          += size;
  1520.      }
  1521.  
  1522.      /* Check selected button image */
  1523.      if ((image = (struct Image *)gad->SelectRender) &&
  1524.                     (data = (BYTE *)image->ImageData) &&
  1525.                        !(TypeOfMem(data) & MEMF_CHIP)) {
  1526.         size = (image->Width / 16 + (image->Width & 15 ? 1 : 0))
  1527.                      * image->Height * image->Depth * 2;
  1528.         CopyMem(data, buffer, size);
  1529.         image->ImageData = (UWORD *)buffer;
  1530.         buffer          += size;
  1531.      }
  1532.      break;
  1533.  
  1534.       case EXTENDED_GADGET_TYPE_SLIDER_PROP :
  1535.  
  1536.      /* Check image of proportional gadget knob */
  1537.      if (flags & EXTENDED_GADGET_FLAG_KNOB_IMAGE) {
  1538.         image = (struct Image *)gad->GadgetRender;
  1539.         if ((data = (BYTE *)image->ImageData) &&
  1540.                        !(TypeOfMem(data) & MEMF_CHIP)) {
  1541.            size = (image->Width / 16 + (image->Width & 15 ? 1 : 0))
  1542.                      * image->Height * image->Depth * 2;
  1543.            CopyMem(data, buffer, size);
  1544.            image->ImageData = (UWORD *)buffer;
  1545.            buffer          += size;
  1546.         }
  1547.      }
  1548.      break;
  1549.    }
  1550.    return(buffer);
  1551. }
  1552.